﻿using System;
using SilverChart.Core.Configuration;
using SilverChart.Core.Service;
using System.Json;
using System.Collections.Generic;
using System.Reflection;

namespace SilverChart.JsonConfiguration {
    public class JsonConfigurationParser : AbstractConfigurationParser {
        private JsonValue data;

        public JsonConfigurationParser(JsonValue value) {
            data = value;
        }

        protected override ConfigurationItem CreateConfigurationItem(Type type, String itemName) {
            JsonValue itemValue = null;
            if (data != null && data.JsonType == JsonType.Object &&
                (data as JsonObject).TryGetValue(itemName, out itemValue) &&
                (itemValue.JsonType == JsonType.Object || itemValue.JsonType == JsonType.Array)) {

                JsonConfigurationParser parser = new JsonConfigurationParser(itemValue);
                ConfigurationItem configItem = AbstractConfigurationItem.CreateInstance(type, parser);

                if (configItem != null) {
                    parser.Configuration = configItem;
                }
                else {
                    throw new ArgumentException("Can not create instance of type " + type.FullName);
                }

                return configItem;
            }
            return null;
        }

        public override String GetItemValue(String itemName) {
            JsonValue itemValue = null;
            if (data != null && data.JsonType == JsonType.Object && 
                (data as JsonObject).TryGetValue(itemName, out itemValue)) {
                return GetItemValue(itemValue);
            }
            return null;
        }

        protected override IList<ConfigurationItem> CreateConfigurationCollectionItem(Type type, string itemName) {
            if (data != null && data.JsonType == JsonType.Array) {
                JsonArray items = data as JsonArray;
                IList<ConfigurationItem> configItems = new List<ConfigurationItem>();
                foreach (JsonValue value in items) {
                    if (value.JsonType == JsonType.Object || value.JsonType == JsonType.Array) {
                        JsonConfigurationParser parser = new JsonConfigurationParser(value);
                        ConfigurationItem item = AbstractConfigurationItem.CreateInstance(type, parser);
                        parser.Configuration = item;
                        configItems.Add(item);
                    }
                }
                return configItems;
            }
            return null;
        }

        protected override bool IsItemSupportCollection(string itemName) {
            //ignore itemName in Json
            if (data != null && data.JsonType == JsonType.Array) {
                return true;
            }
            return false;
        }

        protected override IList<string> GetItemValues(string itemName) {
            if (data != null && data.JsonType == JsonType.Array) {
                JsonArray itemValues = data as JsonArray;
                IList<String> values = new List<String>();
                foreach (JsonValue value in itemValues) {
                    values.Add(GetItemValue(value));
                }
                return values;
            }
            return null;
        }

        private string GetItemValue(JsonValue itemValue) {
            String str = null;
            if (itemValue != null) {
                str = itemValue.ToString();
                if (itemValue.JsonType == JsonType.String) {
                    str = str.Substring(1, str.Length - 2);
                }
                str = str.Replace(@"\\", @"\").Replace(@"\/", @"/");
            }
            return str;
        }
    }
}
